/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.asportoonline.integration;

import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import org.asportoonline.entities.Cliente;
import org.asportoonline.entities.Indirizzo;
import org.asportoonline.entities.Locale;
import org.asportoonline.entities.Prenotazione;
import org.asportoonline.entities.Prodotto;

/**
 * Questa classe implementa i metodi di LocaleFacade, necessari per interfacciarsi con l'entità
 * Locale.
 * 
 * @author fe
 * @see LocaleFacade
 */
@Stateless
public class LocaleFacadeImplementation extends AbstractFacade<Locale> implements LocaleFacade {
    @PersistenceContext(unitName = "AsportoOnline-ejbPU")
    private EntityManager em;

    protected EntityManager getEntityManager() {
        return em;
    }

    public LocaleFacadeImplementation() {
        super(Locale.class);
    }
    
    /**
     * Cerca un Locale in base all'ID.
     * 
     * @param id ID del locale.
     * @return se l'ID esiste restituisce il Locale, altrimenti restituisce null.
     * @see Locale
     */
    @Override
    public Locale find(long id) {
        Query query = em.createQuery("select l from Locale l where l.idLocale = :idlocale");
        query.setParameter("idlocale", id);
        List<Locale> ll = (List<Locale>)query.getResultList();
        if(ll==null || ll.isEmpty())    return null;
        return (Locale)ll.get(0);
    }

    
    /**
     * Cerca un Locale in base al nome.
     * 
     * @param nome nome del locale.
     * @return se il nome esiste restituisce il Locale, altrimenti restituisce null.
     * @see Locale
     */
    public Locale find(String nome) {
        Query query = em.createQuery("select l from Locale l where l.nome = :nome");
        query.setParameter("nome", nome);
        List<Locale> ll = (List<Locale>)query.getResultList();
        if(ll==null || ll.isEmpty())    return null;
        return (Locale)ll.get(0);
    }
    
    /**
     * Recupera tutti i Locali di cui un certo Cliente (venditore) è proprietario.
     * 
     * @param c Cliente proprietario
     * @return se il Cliente esiste e possiede almeno un Locale, restituisce la lista dei Locali, altrimenti restituisce null.
     * @see Locale
     */
    public List<Locale> fetch_vendor_locals(Cliente c) {
        Query query = em.createQuery("select l from Locale l where l.proprietario = :prop");
        query.setParameter("prop", c);
        List<Locale> ll = (List<Locale>)query.getResultList();
        
        if(ll==null || ll.isEmpty()) return null;        
        else  return ll;
    }
    
    /**
     * Modifica un locale esistente.
     * 
     * @param locale 
     * @see Locale
     */
    @Override
    public void edit(Locale l) {
        em.merge(l);
    }
    
    /**
     * Recupera tutte le località in cui è presente almeno un Locale.
     * 
     * @return restituisce una lista contenente tutti i nomi delle città in cui è presente almeno un locale;
     * se non ci sono locali registrati restituisce null.
     */
    public List<String> fetch_all_locality() {
        Query query = em.createQuery("select distinct l.indirizzo.citta from Locale l order by l.indirizzo.citta");
        List<String> lc = (List<String>)query.getResultList();
        
        if(lc==null || lc.isEmpty()) {
            return null;            
        }
        
        return lc;
    }    
    
    /**
     * Recupera tutte i locali presenti in una data città.
     * 
     * @param locality città di cui si vogliono ottenere i locali.
     * @return restituisce una lista contenente tutti i locali della città in input;
     * se non ci sono locali registrati in tale città restituisce null.
     * @see Locale
     */
    public List<Locale> find_for_locality(String locality) {
        Query query = em.createQuery("select l from Locale l where l.indirizzo.citta = :loc order by l.nome");
        query.setParameter("loc", locality);
        List<Locale> ll = (List<Locale>)query.getResultList();
        return ll;
    }
    
    /**
     * Rimuove un locale.
     * 
     * @param locale 
     * @see Locale
     */
    @Override
    public void remove(Locale locale) {
        //elimino tutti i prodotti prenotati
        Query query = em.createQuery("delete from ProdottoPrenotato pp where pp.idProdottoPrenotato.idpren = :idpren");
        List<Prenotazione> listapren = locale.getPrenotazioni();
        Prenotazione pren;
        if(listapren != null) {
            for(int i=0; i<listapren.size(); i++) {
                pren = listapren.get(i);
                query.setParameter("idpren", pren.getIdPrenotazione());
                query.executeUpdate();
            }
        }
        
        //elimino tutte le prenotazioni del locale
        query = em.createQuery("delete from Prenotazione p where p.idPrenotazione = :idpren");
        listapren = locale.getPrenotazioni();
        if(listapren != null) {
            for(int i=0; i<listapren.size(); i++) {
                pren = listapren.get(i);
                query.setParameter("idpren", pren.getIdPrenotazione());
                query.executeUpdate();
            }
        }
       
        //elimino tutti i prodotti del locale
        query = em.createQuery("delete from Prodotto p where p.idProdotto = :idprod");
        List<Prodotto> listaprod = locale.getProdotti();
        Prodotto prod;
        if(listaprod != null) {
            for(int i=0; i<listaprod.size(); i++) {
                prod = listaprod.get(i);
                query.setParameter("idprod", prod.getIdProdotto());
                query.executeUpdate();
            }
        }
        
        //elimino il locale
        query = em.createQuery("delete from Locale l where l.idLocale = :idlocale");
        query.setParameter("idlocale", locale.getIdLocale());
        query.executeUpdate();
    }
}
